home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / ab20_archive / utilities / file / gnutar.lzh / src.lzh / msd_dir.c < prev    next >
C/C++ Source or Header  |  1991-05-06  |  4KB  |  217 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8.  
  9. #include    <sys/types.h>
  10. #include    <sys/stat.h>
  11. #include    <sys/dir.h>
  12. #include    <malloc.h>
  13. #include    <string.h>
  14. #include    <dos.h>
  15.  
  16. #ifndef    NULL
  17. # define    NULL    0
  18. #endif    /* NULL */
  19.  
  20. #ifndef    MAXPATHLEN
  21. # define    MAXPATHLEN    255
  22. #endif    /* MAXPATHLEN */
  23.  
  24. /* attribute stuff */
  25. #define    A_RONLY        0x01
  26. #define    A_HIDDEN    0x02
  27. #define    A_SYSTEM    0x04
  28. #define    A_LABEL        0x08
  29. #define    A_DIR        0x10
  30. #define    A_ARCHIVE    0x20
  31.  
  32. /* dos call values */
  33. #define    DOSI_FINDF    0x4e
  34. #define    DOSI_FINDN    0x4f
  35. #define    DOSI_SDTA    0x1a
  36.  
  37. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  38. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  39. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  40.  
  41. /* what find first/next calls look use */
  42. typedef struct {
  43.     char        d_buf[21];
  44.     char        d_attribute;
  45.     unsigned short    d_time;
  46.     unsigned short    d_date;
  47.     long        d_size;
  48.     char        d_name[13];
  49. } Dta_buf;
  50.  
  51. static    char    *getdirent();
  52. static    void    setdta();
  53. static    void    free_dircontents();
  54.  
  55. static    Dta_buf        dtabuf;
  56. static    Dta_buf        *dtapnt = &dtabuf;
  57. static    union REGS    reg, nreg;
  58.  
  59. #if    defined(M_I86LM)
  60. static    struct SREGS    sreg;
  61. #endif
  62.  
  63. DIR    *
  64. opendir(name)
  65.     char    *name;
  66. {
  67.     struct    stat        statb;
  68.     DIR            *dirp;
  69.     char            c;
  70.     char            *s;
  71.     struct _dircontents    *dp;
  72.     char            nbuf[MAXPATHLEN + 1];
  73.     
  74.     if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  75.         return (DIR *) NULL;
  76.     if (Newisnull(dirp, DIR))
  77.         return (DIR *) NULL;
  78.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  79.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  80.     else
  81.         (void) strcat(strcpy(nbuf, name), "*.*");
  82.     dirp->dd_loc = 0;
  83.     setdta();
  84.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  85.     if ((s = getdirent(nbuf)) == (char *) NULL)
  86.         return dirp;
  87.     do {
  88.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  89.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  90.         {
  91.             if (dp)
  92.                 free((char *) dp);
  93.             free_dircontents(dirp->dd_contents);
  94.             return (DIR *) NULL;
  95.         }
  96.         if (dirp->dd_contents)
  97.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  98.         else
  99.             dirp->dd_contents = dirp->dd_cp = dp;
  100.         (void) strcpy(dp->_d_entry, s);
  101.         dp->_d_next = (struct _dircontents *) NULL;
  102.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  103.     dirp->dd_cp = dirp->dd_contents;
  104.  
  105.     return dirp;
  106. }
  107.  
  108. void
  109. closedir(dirp)
  110.     DIR    *dirp;
  111. {
  112.     free_dircontents(dirp->dd_contents);
  113.     free((char *) dirp);
  114. }
  115.  
  116. struct direct    *
  117. readdir(dirp)
  118.     DIR    *dirp;
  119. {
  120.     static    struct direct    dp;
  121.     
  122.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  123.         return (struct direct *) NULL;
  124.     dp.d_namlen = dp.d_reclen =
  125.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  126.     strlwr(dp.d_name);        /* JF */
  127.     dp.d_ino = 0;
  128.     dirp->dd_cp = dirp->dd_cp->_d_next;
  129.     dirp->dd_loc++;
  130.  
  131.     return &dp;
  132. }
  133.  
  134. void
  135. seekdir(dirp, off)
  136.     DIR    *dirp;
  137.     long    off;
  138. {
  139.     long            i = off;
  140.     struct _dircontents    *dp;
  141.  
  142.     if (off < 0)
  143.         return;
  144.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  145.         ;
  146.     dirp->dd_loc = off - (i + 1);
  147.     dirp->dd_cp = dp;
  148. }
  149.  
  150. long
  151. telldir(dirp)
  152.     DIR    *dirp;
  153. {
  154.     return dirp->dd_loc;
  155. }
  156.  
  157. static    void
  158. free_dircontents(dp)
  159.     struct    _dircontents    *dp;
  160. {
  161.     struct _dircontents    *odp;
  162.  
  163.     while (dp) {
  164.         if (dp->_d_entry)
  165.             free(dp->_d_entry);
  166.         dp = (odp = dp)->_d_next;
  167.         free((char *) odp);
  168.     }
  169. }
  170.  
  171. static    char    *
  172. getdirent(dir)
  173.     char    *dir;
  174. {
  175.     if (dir != (char *) NULL) {        /* get first entry */
  176.         reg.h.ah = DOSI_FINDF;
  177.         reg.h.cl = ATTRIBUTES;
  178. #if    defined(M_I86LM)
  179.         reg.x.dx = FP_OFF(dir);
  180.         sreg.ds = FP_SEG(dir);
  181. #else
  182.         reg.x.dx = (unsigned) dir;
  183. #endif
  184.     } else {                /* get next entry */
  185.         reg.h.ah = DOSI_FINDN;
  186. #if    defined(M_I86LM)
  187.         reg.x.dx = FP_OFF(dtapnt);
  188.         sreg.ds = FP_SEG(dtapnt);
  189. #else
  190.         reg.x.dx = (unsigned) dtapnt;
  191. #endif
  192.     }
  193. #if    defined(M_I86LM)
  194.     intdosx(®, &nreg, &sreg);
  195. #else
  196.     intdos(®, &nreg);
  197. #endif
  198.     if (nreg.x.cflag)
  199.         return (char *) NULL;
  200.  
  201.     return dtabuf.d_name;
  202. }
  203.  
  204. static    void
  205. setdta()
  206. {
  207.     reg.h.ah = DOSI_SDTA;
  208. #if    defined(M_I86LM)
  209.     reg.x.dx = FP_OFF(dtapnt);
  210.     sreg.ds = FP_SEG(dtapnt);
  211.     intdosx(®, &nreg, &sreg);
  212. #else
  213.     reg.x.dx = (int) dtapnt;
  214.     intdos(®, &nreg);
  215. #endif
  216. }
  217.